﻿#pragma once

#include <cassert>
#include <vector>

namespace CAGD
{

/**
 * @brief 样条基类.
 *
 */
class Spline
{
  public:
    /**
     * @brief 找到 u 所在的节点区间 [u_i, u_{i+1}).
     * @return
     * @param u
     * @param deg
     * @param knots
     * @see
     */
    static int FindSpan(double u, int deg, const std::vector<double> &knots);

    /**
     * @brief 找到 [u_k,u_{k+1}) 和之前 u 出现的次数.
     * @return
     * @param k
     * @param u
     * @param deg
     * @param knots
     * @see
     */
    static int FindMult(int k, double u, int deg, const std::vector<double> &knots);

    /**
     * @brief 计算所有代入 u 后不为零的 deg 次基函数.
     * @return
     * @param i
     * @param u
     * @param deg
     * @param knots
     * @see
     */
    static std::vector<double> Basis(int i, double u, int deg, const std::vector<double> &knots);

    /**
     * @brief 计算所有代入 u 后不为零的 deriv 阶导基函数，注意无法计算重节点处的导数.
     * @return
     * @param deriv
     * @param i
     * @param u
     * @param deg
     * @param knots
     * @see
     */
    static std::vector<std::vector<double>> DerivBasis(int deriv, int i, double u, int deg,
                                                       const std::vector<double> &knots);

    /**
     * @brief 计算所有代入 u 后不为零的不大于 deg 次基函数.
     * @return
     * @param i
     * @param u
     * @param deg
     * @param knots
     * @see
     */
    static std::vector<std::vector<double>> DerivAllBasis(int i, double u, int deg, const std::vector<double> &knots);
};

} // namespace CAGD
